using AdminApiTemplate.Cache;
using AdminApiTemplate.Common.Helpers;
using AdminApiTemplate.ThirdParty.Email;
using System.Text;

namespace AdminApiTemplate.Tasks.Email
{
    /// <summary>
    /// 发送邮件任务
    /// </summary>
    public class SendEmailTask : ITask
    {
        private readonly MySqlHelper _defaultQuery;

        public SendEmailTask(
            MySqlHelper defaultQuery)
        {
            _defaultQuery = defaultQuery;
        }

        public void Execute()
        {
            var sql = "SELECT Id,ToEmail from queuesendemail WHERE SendingStatus=1 ORDER BY Id LIMIT 100";
            var items = _defaultQuery.GetList<SendEmailItem>(sql);
            if (items.Count == 0)
            {
                return;
            }

            var run = ConfigHelper.GetSysConfig<bool>("RunSendEmailQueue", false);
            if (!run)
            {
                LogHelper.WriteAsync("未开启发送邮件队列：RunSendEmailQueue", "Task");
                return;
            }

            var emailSubjectTemplateName = ConfigHelper.GetSysConfig<string>("SendEmailSubjectTemplateName", "Subject.txt");
            var emailSubjectTemplateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Templates", "Email", emailSubjectTemplateName);
            if (!File.Exists(emailSubjectTemplateFile))
            {
                LogHelper.WriteAsync("未找到邮件标题模板："+emailSubjectTemplateFile, "Email");
                return;
            }

            var emailContentTemplateName = ConfigHelper.GetSysConfig<string>("SendEmailContentTemplateName", "ContentTemplate.html");
            var emailContentTemplateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Templates", "Email", emailContentTemplateName);
            if (!File.Exists(emailContentTemplateFile))
            {
                LogHelper.WriteAsync("未找到邮件内容模板："+emailContentTemplateFile, "Email");
                return;
            }

            var emailSubject = File.ReadAllText(emailSubjectTemplateFile, Encoding.UTF8);
            var emailContentTemplate = File.ReadAllText(emailContentTemplateFile, Encoding.UTF8);

            var userName = ConfigHelper.GetSysConfig<string>("SendEmailUserName", "kolify.shop");
            var interval = ConfigHelper.GetSysConfig<int>("SendEmailInterval", 1000);
            var enableSSL = ConfigHelper.GetSysConfig<bool>("SendEmailEnableSSL", true);

            sql=$"update queuesendemail set SendingStatus=2,SendingTime=NOW() where Id in ({string.Join(",", items.Select(o => o.Id.GetValueOrDefault()))})";
            _defaultQuery.Execute(sql);

            for (var i = 0; i<items.Count; i++)
            {
                if (i > 0)
                {
                    var r = RandomHelper.Instance.Next(interval, interval+2000);
                    Thread.Sleep(r);
                }

                var item = items[i];
                if (string.IsNullOrEmpty(item.ToEmail))
                {
                    sql = $"update queuesendemail set SendingStatus=4,Remark=@remark where Id={item.Id.GetValueOrDefault()}";
                    _defaultQuery.Execute(sql, new { remark = "发送失败，收件邮箱不正确" });
                    continue;
                }

                sql = $"SELECT t1.Email FromEmail,t1.`Password` FromEmailPassword,t1.Smtp FromEmailSmtp,t1.`Port` FromEmailPort from configsendemail t1 WHERE t1.`Disabled`=0 AND t1.`Success`<t1.`MaxSend` ORDER BY RAND() LIMIT 1";
                var fromEmails = _defaultQuery.GetList<SendEmailItem>(sql);
                if (fromEmails.Count == 0)
                {
                    sql = $"update queuesendemail set SendingStatus=4,Remark=@remark where Id={item.Id.GetValueOrDefault()}";
                    _defaultQuery.Execute(sql, new { remark = "发送失败，没有可用的发件邮箱" });
                    continue;
                }

                item.FromEmail = fromEmails[0].FromEmail;
                item.FromEmailPassword = fromEmails[0].FromEmailPassword;
                item.FromEmailSmtp = fromEmails[0].FromEmailSmtp;
                item.FromEmailPort = fromEmails[0].FromEmailPort;

                sql = $"update queuesendemail set FromEmail=@FromEmail,FromEmailPassword=@FromEmailPassword,FromEmailSmtp=@FromEmailSmtp,FromEmailPort=@FromEmailPort where Id={item.Id.GetValueOrDefault()}";
                _defaultQuery.Execute(sql, item);

                var toemail = item.ToEmail.Split(',')[0];
                var content = emailContentTemplate;
                var emailHelper = new EmailHelper(item.FromEmailSmtp, item.FromEmailPort.GetValueOrDefault(), enableSSL);
                var sendResult = emailHelper.Send(toemail, item.FromEmail, item.FromEmailPassword, userName, emailSubject, content);
                if (sendResult.Code == 0)
                {
                    sql = $"update queuesendemail set SendingStatus=3,Remark=null where Id={item.Id.GetValueOrDefault()}";
                    _defaultQuery.Execute(sql);

                    sql = $"update configsendemail set Success=Success+1 where Email=@FromEmail";
                    _defaultQuery.Execute(sql, item);
                }
                else
                {
                    var remark = sendResult.Message;
                    sql = $"update queuesendemail set SendingStatus=4,Remark=@remark where Id={item.Id.GetValueOrDefault()}";
                    _defaultQuery.Execute(sql, new { remark });

                    //发件邮箱账号密码错误或者发送受限
                    if (sendResult.Code== 1 || sendResult.Code==3)
                    {
                        sql = $"update configsendemail set Fail=Fail+1,Disabled=1,DisabledTime=NOW() where Email=@FromEmail";
                        _defaultQuery.Execute(sql, item);
                    }
                    else
                    {
                        sql = $"update configsendemail set Fail=Fail+1 where Email=@FromEmail";
                        _defaultQuery.Execute(sql, item);
                    }
                }
            }
        }
    }

    public class SendEmailItem
    {
        /// <summary>
        /// Id
        /// </summary>
        public int? Id { get; set; }

        /// <summary>
        /// 收件人
        /// </summary>
        public string ToEmail { get; set; }

        /// <summary>
        /// 发件人邮箱
        /// </summary>
        public string FromEmail { get; set; }

        /// <summary>
        /// 发件人邮箱密码
        /// </summary>
        public string FromEmailPassword { get; set; }

        /// <summary>
        /// 发件人邮箱服务器地址
        /// </summary>
        public string FromEmailSmtp { get; set; }

        /// <summary>
        /// 发件人邮箱服务器端口
        /// </summary>
        public int? FromEmailPort { get; set; }
    }
}
